//-----------------------------------------------------------------------------
// File: MultiPointShapeBase.cs
//
// Copyright (c) Dmitry Shuklin. All rights reserved.
//-----------------------------------------------------------------------------
using System;

namespace ObjectiveDraw.Platform
{
	
	/// <summary>
	/// Summary description for MultiPointShapeBase.
	/// </summary>
	public class MultiPointShapeBase: DrawerShapeBase
	{

		public MultiPointShapeBase()
		{
			//
			// TODO: Add constructor logic here
			//
		}

		public int CreatingPoint = 0;


		#region IDrawerShape Members

		public override bool UpdateShape(DrawerChartBase control, ChartInfoArgs cinfo, Cerebrum.Direct3D.Forms.DeviceEventArgs de, bool idle, out UpdateShapeInfo uinfo)
		{
			DrawerChartContext context = control.Context;
			base.UpdateShape (control, cinfo, de, idle, out uinfo);

			if(m_Selected && this.CreatingPoint<0)
			{

				System.Drawing.RectangleF _rect = control.SurfaceRectangle;
				foreach(DrawerShapes.MousePoint mp in this.m_MousePoints)
				{
					Cerebrum.Direct3D.Forms.ShapeControl frame = this.GetControlPoint(mp) as Cerebrum.Direct3D.Forms.ShapeControl;
					if(frame==null)
					{
						frame = new Cerebrum.Direct3D.Forms.ShapeControl();
						frame.Z = 0.01f;
						frame.ForeColor = this.m_ShapeControlPrimaryColor;
						control.Controls.Insert(0, frame);
						this.AddControlPoint(mp, frame);
					}

					float x1 = OffsetFromAbscissa(control, mp.Abscissa);

					float y1 = OffsetFromOrdinate(control, mp.Ordinate);

					float w = 10;
					float w2 = w / 2;

					frame.SetBounds(x1 - w2 - _rect.X, y1 - w2 - _rect.Y, w, w, System.Windows.Forms.BoundsSpecified.All);
				}
			}
			return true;
		}

		public override void OnMouseDown(ObjectiveDraw.Platform.DrawerChartBase control, System.Windows.Forms.MouseEventArgs e)
		{
			if(this.CreatingPoint >= 0)
			{
				DrawerShapes.MousePoint mp = (DrawerShapes.MousePoint)this.m_MousePoints[this.CreatingPoint];
				mp.Abscissa = AbscissaFromMouse(control, e.X);
				mp.Ordinate = OrdinateFromMouse(control, e.Y);
			}
			else
			{
				m_DragState = new MouseDragState();
				foreach(DrawerShapes.MousePoint mp in this.m_MousePoints)
				{
					DrawerShapes.MousePoint mpc = mp.Clone() as DrawerShapes.MousePoint;
					mpc.Original = mp;
					m_DragState.MousePoints.Add(mpc);
				}
				m_DragState.MouseDownPoint = new System.Drawing.Point(e.X, e.Y);
			}
		}

		public override void OnMouseMove(ObjectiveDraw.Platform.DrawerChartBase control, System.Windows.Forms.MouseEventArgs e)
		{
			DrawerChartContext context = control.Context;
			if(this.CreatingPoint >= 0)
			{
				DrawerShapes.MousePoint mp = (DrawerShapes.MousePoint)this.m_MousePoints[this.CreatingPoint];
				mp.Abscissa = AbscissaFromMouse(control, e.X);
				mp.Ordinate = OrdinateFromMouse(control, e.Y);
			}
			else if(m_DragState!=null)
			{
				float _dx = (float)((m_DragState.MouseDownPoint.X - e.X) / context.AbscissaPosition.Scale);
				float _dy = (float)((m_DragState.MouseDownPoint.Y - e.Y) / context.OrdinatePosition.Scale);

				foreach(DrawerShapes.MousePoint mp in this.m_DragState.MousePoints)
				{
					mp.Original.Abscissa = mp.Abscissa - _dx;
					mp.Original.Ordinate = mp.Ordinate + _dy;
				}
			}
			control.Invalidate();
		}

		public override void OnMouseUp(ObjectiveDraw.Platform.DrawerChartBase control, System.Windows.Forms.MouseEventArgs e, ref bool CaptureMouse)
		{
			if(this.CreatingPoint >= 0)
			{
				DrawerShapes.MousePoint mp = (DrawerShapes.MousePoint)this.m_MousePoints[this.CreatingPoint];
				mp.Abscissa = AbscissaFromMouse(control, e.X);
				mp.Ordinate = OrdinateFromMouse(control, e.Y);
				this.CreatingPoint++;
				if(this.CreatingPoint >= this.m_MousePoints.Count) 
				{
					this.CreatingPoint = -1;
				}
				else
				{
					CaptureMouse = true;
				}
			}
			m_DragState = null;
			control.Invalidate();
		}

		public override bool GetAbscissaExtents(ref float min, ref float max)
		{
			if(this.CreatingPoint < 0)
			{
				return base.GetAbscissaExtents (ref min, ref max);
			}
			else
			{
				return false;
			}
		}

		public override bool GetOrdinateExtents(ref float min, ref float max)
		{
			if(this.CreatingPoint < 0)
			{
				return base.GetOrdinateExtents (ref min, ref max);
			}
			else
			{
				return false;
			}
		}

		#endregion


		protected override bool LoadVariables(ObjectiveDraw.Platform.Serialization.FallbackChain storage, SerializationContext context)
		{
			this.CreatingPoint = -1;
			return base.LoadVariables (storage, context);
		}


		/*--protected override bool LoadVariables(bool force)
		{
			bool r = base.LoadVariables (force);
			this.m_MousePoints.Clear();
			int points = (int)Workspace.LoadVariable(false, this, KnownDrawerVariables.ShapeControlPointCount);
			for(int i=0;i<points;i++)
			{
				MousePoint mp = new MousePoint();
				mp.Ordinate= (float)Workspace.LoadVariable(this, KnownDrawerVariables.ShapeControlPointOrdinate + "." + i, 0);
				mp.DateTime = (System.DateTime)Workspace.LoadVariable(this, KnownDrawerVariables.ShapeControlPointDateTime + "." + i, System.DateTime.Today);
				this.m_MousePoints.Add(mp);
			}
			this.CreatingPoint = -1;
			return r;
		}

		protected override bool SaveVariables()
		{
			bool r = base.SaveVariables ();
			int points = 0;
			foreach(MousePoint mp in this.m_MousePoints)
			{
				Workspace.SaveVariable(this, KnownDrawerVariables.ShapeControlPointOrdinate + "." + points, mp.Ordinate);
				Workspace.SaveVariable(this, KnownDrawerVariables.ShapeControlPointDateTime + "." + points, mp.DateTime);
				points++;
			}
			Workspace.SaveVariable(this, KnownDrawerVariables.ShapeControlPointCount, points);
			return r;
		}--*/


		protected override void OnControlPointMouseMove(object sender, System.Windows.Forms.MouseEventArgs e)
		{
			if(m_MouseDown)
			{
				Cerebrum.Direct3D.Forms.Control ctl = sender as Cerebrum.Direct3D.Forms.Control;
				foreach(DrawerShapes.MousePoint mp in this.m_MousePoints)
				{
					if(ctl == this.GetControlPoint(mp))
					{
						mp.Abscissa = AbscissaFromMouse((DrawerChartBase)ctl.Parent, (e.X + ctl.SurfaceRectangle.X) - m_DownMousePosition.X);
						mp.Ordinate = OrdinateFromMouse((DrawerChartBase)ctl.Parent, (e.Y + ctl.SurfaceRectangle.Y) - m_DownMousePosition.Y);
						ctl.Invalidate();
					}
				}
			}
			base.OnControlPointMouseMove(sender, e);

		}

	}
}
